package com.ayz.gateway.core.session.defaults;

import com.ayz.gateway.core.context.config.Configuration;
import com.ayz.gateway.core.datasource.DatasourceFactory;
import com.ayz.gateway.core.datasource.RpcStatement;
import com.ayz.gateway.core.rpc.IGatewayApi;
import com.ayz.gateway.core.rpc.MappedMethod;
import com.ayz.gateway.core.rpc.RemotingResponseCallback;
import com.ayz.gateway.core.session.GatewaySession;
import com.ayz.gateway.core.session.convert.HttpStatToRpcStatConvertFactory;
import com.ayz.gateway.core.session.executor.DefaultExecutor;
import com.ayz.gateway.core.session.executor.Executor;
import com.ayz.gateway.core.session.http.HttpStatement;
import com.ayz.gateway.core.session.processor.RpcPostProcessor;
import com.ayz.gateway.core.session.processor.RpcPostProcessorRegistry;
import lombok.Data;

/**
 * @ClassName DefaultGatewaySession
 * @Description TODO: 默认的网关会话
 * @Author 快乐的星球
 * @Date 2023/5/8 11:53
 * @Version 1.0
 **/
@Data
public class DefaultGatewaySession implements GatewaySession {
    /**
     * 立足于网关上下文的配置项
     */
    private Configuration configuration;
    /**
     * HTTP请求的参数
     */
    private HttpStatement httpStatement;

    /**
     * 响应的回调处理函数
     */
    private RemotingResponseCallback responseCallback;
    /**
     * 数据源工厂
     */
    private DatasourceFactory datasourceFactory;
    /**
     * Rpc增强器链条的注册器
     */
    private RpcPostProcessorRegistry postProcessorRegistry;

    public DefaultGatewaySession(Configuration configuration,DatasourceFactory datasourceFactory,RpcPostProcessorRegistry rpcPostProcessorRegistry) {
        this.configuration=configuration;
        this.datasourceFactory=datasourceFactory;
        this.postProcessorRegistry=rpcPostProcessorRegistry;
    }

    public DefaultGatewaySession(Configuration configuration, HttpStatement httpStatement) {
        this.configuration=configuration;
        this.httpStatement = httpStatement;
    }

    public Configuration getConfiguration() {
        return this.configuration;
    }

    @Override
    public IGatewayApi getResource(String rpcResource) {
        return this.configuration.getGenericReference(rpcResource);
    }
    @Override
    public HttpStatement getHttpStatement() {
        return this.httpStatement;
    }

    @Override
    public void open() throws Exception {
        HttpStatement httpStatement = getHttpStatement();
        httpStatement.setResponseCallback(responseCallback);
        //1: 根据当前的请求uri 从全局上下文中获取映射器MappedMethod
        String httpUri = httpStatement.getHttpUri();
        MappedMethod mappedMethod = this.configuration.getMappedMethod(httpUri);
        //2.根据请求的参数封装RPC调用参数封装类 RpcStatement
        RpcStatement rpcStatement = HttpStatToRpcStatConvertFactory.convert(httpStatement, mappedMethod);
        rpcStatement.setDatasourceFactory(getDatasourceFactory());
        //4:获取执行器去执行RpcStatement(可以视为一个RPC调用计划)
        Executor executor=new DefaultExecutor(this);
        executor.execute(rpcStatement);
    }

    @Override
    public RpcPostProcessor[] getRpcPostProcessors() {
        return this.postProcessorRegistry.getOrderedPostProcessors();
    }
}
